package com.lenovo.spider.component;

import com.lenovo.spider.domain.Task;

import java.util.ServiceLoader;

/**
 * 任务处理器
 *
 * @author <a href="mailto:liuhan3@lenovo.com">HanL(liuhan3)</a>
 * on 2018/4/11 21:04
 */
public class TaskProcessor<T extends TaskProcess> implements TaskProcess {

    private final ServiceLoader<T> serviceLoader;

    private TaskProcessor(Class<T> cls) {
        this.serviceLoader = ServiceLoader.load(cls);
    }

    @Override
    public boolean support(Task task) {
        return true;
    }

    @Override
    public Task handle(Task task) {
        Task tmp = task;
        for (TaskProcess taskProcess : this.serviceLoader) {
            if (taskProcess.support(tmp)) {
                tmp = taskProcess.process(tmp);
            }
        }
        return tmp;
    }

    /**
     * 下载器
     *
     * @return
     */
    public static TaskProcessor<Downloader> downloader() {
        return newInstance(Downloader.class);
    }

    public static TaskProcessor<PreDownloaderInterceptor> preInterceptor() {
        return newInstance(PreDownloaderInterceptor.class);
    }

    public static TaskProcessor<AfterDownloaderInterceptor> afterInterceptor() {
        return newInstance(AfterDownloaderInterceptor.class);
    }


    /**
     * 页面处理器
     *
     * @return
     */
    public static TaskProcessor<PageParser> pageParser() {
        return newInstance(PageParser.class);
    }

    /**
     * 结果处理器
     *
     * @return
     */
    public static TaskProcessor<Pipeline> pipeline() {
        return newInstance(Pipeline.class);
    }

    /**
     * 异常处理
     *
     * @return
     */
    public static TaskProcessor<ExceptionHandler> exceptionHandler() {
        return newInstance(ExceptionHandler.class);
    }

    /**
     * @param cls
     * @param <T>
     * @return
     */
    public static <T extends TaskProcess> TaskProcessor<T> newInstance(Class<T> cls) {
        return new TaskProcessor<>(cls);
    }
}
